
import threading
import paddlehub as hub
import numpy as np
import cv2
import time
from typing import List, Dict

class OCRService:
    """
    内存版OCR服务，无需文件存储
    功能改进：
    - 直接处理二进制图像数据
    - 移除文件系统依赖
    - 支持多种图像格式解码
    """
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not hasattr(self, '_initialized'):
            self._model = None
            self._initialize_model()
            self._initialized = True
            self._lock = threading.RLock()

    def _initialize_model(self):
        """模型初始化（同原实现）"""
        retries = 3
        for attempt in range(retries):
            try:
                print(f"正在加载OCR模型(尝试 {attempt+1}/{retries})...")
                start_time = time.time()
                self._model = hub.Module(
                    name="ch_pp-ocrv3",
                    enable_mkldnn=False,
                )
                # paddle.set_device("gpu")
                load_time = time.time() - start_time
                print(f"模型加载成功，耗时 {load_time:.2f} 秒")
                return
            except Exception as e:
                if attempt == retries - 1:
                    raise RuntimeError(f"模型加载失败，最终错误: {str(e)}")
                time.sleep(2 ** attempt)  # 指数退避重试


    def _decode_image(self, image_data: bytes) -> np.ndarray:
        """内存解码图像（支持PNG/JPG/JPEG）"""
        try:
            nparr = np.frombuffer(image_data, np.uint8)
            img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
            if img is None:
                raise ValueError("不支持的图像格式")
            return img
        except Exception as e:
            raise ValueError(f"图像解码失败: {str(e)}")

    def process_image(self, image_data: bytes) -> List[Dict]:
        """
        内存处理入口方法
        :param image_data: 二进制图像数据
        :return: 结构化识别结果
        """
        try:
            # 解码图像
            start_decode = time.time()
            img = self._decode_image(image_data)
            print(f"图像解码耗时: {time.time()-start_decode:.2f}s")
            # 执行OCR识别
            start_ocr = time.time()
            self._initialize_model()
            result = self._model.recognize_text(
                images=[img],          # 直接传递图像数据
                visualization=False    # 禁用可视化输出
            )
            print(f"OCR识别耗时: {time.time()-start_ocr:.2f}s")

            # 结构化处理结果
            structured_result = []
            for item in result[0]['data']:
                structured_result.append({
                    'text': item['text'],
                    'confidence': round(float(item['confidence']), 4),
                    'position': item['text_box_position']
                })
            
            return structured_result

        except Exception as e:
            error_info = {
                "error": str(e),
                "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
            }
            print(f"OCR处理失败：{error_info}")
            raise